/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sp.dao;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.RollbackException;
import sp.util.LogDatabase;
import sp.util.UserControl;

/**
 *
 * @author StephenCN
 * @param <T>
 */
public class DaoService<T> implements AbstractService<Object> {

    private Class<T> model;
    protected EntityManager em = null;
    private EntityManagerFactory emf;

    protected DaoService(Class<T> model) {
        this.model = model;
    }

    public EntityManager entity() {
        if (em == null) {
            try {
                LogDatabase.readLog();
            } catch (Exception ex) {
                Logger.getLogger(DaoService.class.getName()).log(Level.SEVERE, null, ex);
            }
            Map<String, String> dbProps = new HashMap<>();
            if ("Linux".equals(System.getProperty("os.name"))) {
                dbProps.put("javax.persistence.jdbc.url",
                        String.format("jdbc:mysql://%s:3306/%s?zeroDateTimeBehavior=convertToNull",
                                UserControl.getAuth()[0],
                                UserControl.getAuth()[1]));
                dbProps.put("javax.persistence.jdbc.driver",
                        "com.mysql.jdbc.Driver");
                dbProps.put("javax.persistence.jdbc.password",
                        UserControl.getAuth()[3]);
                dbProps.put("javax.persistence.jdbc.user",
                        UserControl.getAuth()[2]);
            } else {
                dbProps.put("javax.persistence.jdbc.url",
                        String.format("jdbc:mysql://%s:3306/%s?zeroDateTimeBehavior=convertToNull",
                                UserControl.getAuth()[0],
                                UserControl.getAuth()[1]));
                dbProps.put("javax.persistence.jdbc.driver",
                        "com.mysql.jdbc.Driver");
                dbProps.put("javax.persistence.jdbc.password",
                        UserControl.getAuth()[3]);
                dbProps.put("javax.persistence.jdbc.user",
                        UserControl.getAuth()[2]);
            }
            emf = Persistence.createEntityManagerFactory("Sp2Pkl54skPU",dbProps);
            em = emf.createEntityManager();
        }
        return em;
    }

    @Override
    public void save(Object t) {
        try {
            entity().getTransaction().begin();
            entity().persist(t);
            entity().getTransaction().commit();
            if (entity().isOpen()) {
                entity().close();
                em = null;
            }
        } catch (RollbackException e) {
            entity().getTransaction().rollback();
        }
    }

    @Override
    public void update(Object t) {
        try {
            entity().getTransaction().begin();
            entity().merge(t);
            entity().getTransaction().commit();
        } catch (RollbackException e) {
            entity().getTransaction().rollback();
        }
    }

    @Override
    public void delete(Object t) {
        try {
            entity().getTransaction().begin();
            entity().remove(t);
            entity().getTransaction().commit();
        } catch (RollbackException e) {
            entity().getTransaction().rollback();
        }
    }

    @Override
    public List<Object> getAll() {
        String nquery = model + ".findAll";
        return entity().createNamedQuery(nquery).getResultList();
    }

    @Override
    public List<Object> getBy(String NamedQuery, String param, String keyword) {
        return entity().createNamedQuery(NamedQuery).setParameter(param, keyword).getResultList();
    }

    @Override
    public Object getSingleBy(String N, String p, String k) {
        return entity().createNamedQuery(N).setParameter(p, k).getSingleResult();
    }

    @Override
    public T getByID(Object id) {
        return this.entity().find(model, id);
    }
}
